package com.example.compose.retrofit.updataApp

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.*
import android.os.Build
import android.os.Bundle
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.FileProvider
import androidx.core.view.WindowCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.compose.BaseComponentActivity
import com.example.compose.R
import com.example.compose.retrofit.NetWorkManager
import com.example.compose.retrofit.entity.LastUpdate
import com.example.compose.utils.ClickUtils
import com.example.compose.utils.DataStoreManager
import com.example.compose.utils.LogUtil
import kotlinx.coroutines.*
import java.io.File



@SuppressLint("CompositionLocalNaming")
var ActiveLastUpdate = compositionLocalOf<LastUpdate?> { error("No active user found!") }

class CheckUpdateActivity : BaseComponentActivity() {

    private lateinit var checkUpdateViewModel: CheckUpdateViewModel
    private var lastUpdate:LastUpdate? = null
    private lateinit var updateNetworkCallback:ConnectivityManager.NetworkCallback
    private val mainScope: CoroutineScope = MainScope()
    private var stats:Int = -1;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lastUpdate = if (Build.VERSION.SDK_INT >= 33) intent.getSerializableExtra("data",LastUpdate::class.java)
        else  intent.getSerializableExtra("data") as LastUpdate?
        setContent {
            checkUpdateViewModel = viewModel()
            registerNetworkCallback()
            MaterialTheme(
                colors = if(isSystemInDarkTheme()) darkColors() else lightColors(
                    primary = Color(0xFF5A5A5A),
                ),
                typography = if(isSystemInDarkTheme()) Typography(
                    h6 = TextStyle(
                        fontSize = 20.sp,
                        color = Color(0xFFFFFFFF)
                    ),
                    body1 = TextStyle(
                        fontSize = 16.sp,
                        color = Color(0xFFFFFFFF)
                    )
                ) else Typography(
                    h6 = TextStyle(
                        fontSize = 20.sp,
                        color = Color(0xFF000000)
                    ),
                    body1 = TextStyle(
                        fontSize = 16.sp,
                        color = Color(0xFF000000)
                    )
                )
            ){
                val view = LocalView.current
                if (!view.isInEditMode) {
                    SideEffect {
                        val window = (view.context as Activity).window
                        WindowCompat.setDecorFitsSystemWindows(window, false)
                        window.statusBarColor = 0x00000000
                        window.navigationBarColor = android.graphics.Color.BLACK
                    }
                }
                CompositionLocalProvider(ActiveLastUpdate provides lastUpdate) {
                    CheckUpdate {
                        finish()
                    }
                }
            }
        }
    }

    private fun registerNetworkCallback() {
        val connectivityManager = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        updateNetworkCallback = UpdateNetworkCallback()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            connectivityManager.registerDefaultNetworkCallback(updateNetworkCallback)
        } else{
            val builder: NetworkRequest.Builder = NetworkRequest.Builder()
            builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            val networkRequest = builder.build()
            connectivityManager.registerNetworkCallback(networkRequest, updateNetworkCallback)
        }
    }

    override fun onDestroy() {
        val value =  checkUpdateViewModel.downloadStatus.value
        val connectivityManager = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        connectivityManager.unregisterNetworkCallback(updateNetworkCallback)
        if( value is DownloadStatus.DownloadProcess){
            LogUtil.d("保存下载信息${value.currentLength},${value.length},${lastUpdate?.app_version_number?:0}")
            GlobalScope.launch {
                DataStoreManager.saveUpDataVersion(
                    "${value.currentLength},${value.length},${lastUpdate?.app_version_number?:0}"
                )
            }
        }
        mainScope.cancel()
        super.onDestroy()
    }

    inner class UpdateNetworkCallback : ConnectivityManager.NetworkCallback() {
        override fun onCapabilitiesChanged(
            network: Network,
            networkCapabilities: NetworkCapabilities
        ) {
            super.onCapabilitiesChanged(network, networkCapabilities)
            // 表示能够和互联网通信（这个为true表示能够上网）
            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    if(stats == 2) return
                    LogUtil.d("onCapabilitiesChanged#网络类型切换为wifi")
                    if(!checkUpdateViewModel.pause()) return
                    mainScope.launch {
                        delay(200)
                        lastUpdate?.app_url?.let {
                            DataStoreManager.upDataVersion.collect{ version->
                                val split = version.split(",")
                                checkUpdateViewModel.download(it, split[0].toLong() , split[1].toLong() , lastUpdate?.app_version_number, split[2])
                            }
                        }
                    }
                    stats = 2
                } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    if(stats == 1) return
                    LogUtil.d("onCapabilitiesChanged#网络类型切换为移动网络")
                    checkUpdateViewModel.networkChangesFlow()
                    stats = 1
                } else {
                    stats = 3
                    LogUtil.d("onCapabilitiesChanged#其他网络")
                }
            }else{
                stats = 4
                LogUtil.d("onCapabilitiesChanged#无网络")
            }
        }
    }

}

@Composable
fun VersionInformation(checkUpdateViewModel: CheckUpdateViewModel = viewModel(),finish: ()->Unit) {
    val scope = rememberCoroutineScope()
    val lastUpdate = ActiveLastUpdate.current
    RoundedCornersBorder{
        Text(
            text = stringResource(id = R.string.app_up_data),
            modifier = Modifier.padding(0.dp,0.dp,0.dp,5.dp),
            style = MaterialTheme.typography.h6
        )
        Text(
            text = "${stringResource(id = R.string.find_up_data)}${lastUpdate?.app_version}",
            style = MaterialTheme.typography.body1
        )
        Text(
            text = "${stringResource(id = R.string.app_size)}${"%.2f".format(lastUpdate?.app_size?.toFloat()?.div(1024))} MB",
            modifier = Modifier.padding(0.dp,8.dp),
            style = MaterialTheme.typography.body1
        )
        Text(
            text = lastUpdate?.app_update?:"",
            style = MaterialTheme.typography.body1
        )
        Row(modifier = Modifier
            .fillMaxWidth()
            .height(IntrinsicSize.Min), horizontalArrangement = Arrangement.End) {
            TextButton(onClick = {
                finish()
            }) {
                Text(text = stringResource(R.string.remind_later), style = TextStyle(color = Color(0xFF00B2EE), fontSize = 16.sp))
            }
            Spacer(modifier = Modifier.width(5.dp))
            TextButton(onClick = {
                if (ClickUtils.isFastDoubleClick()) return@TextButton
                lastUpdate?.app_url?.let {
                    scope.launch {
                        DataStoreManager.upDataVersion.collect{ version->
                            val split = version.split(",")
                            checkUpdateViewModel.download(it, split[0].toLong() , split[1].toLong() , lastUpdate.app_version_number, split[2])
                        }
                    }
                }
            }) {
                Text(text = stringResource(R.string.up), style = TextStyle(color = Color(0xFFE91E63), fontSize = 16.sp))
            }
        }
    }
}

@Composable
fun DownloadProgress(checkUpdateViewModel: CheckUpdateViewModel = viewModel(),finish: ()->Unit) {

    val scope = rememberCoroutineScope()
    val lastUpdate = ActiveLastUpdate.current
    val downloadStatus by checkUpdateViewModel.downloadStatus.collectAsState()
    when(downloadStatus){
        is DownloadStatus.DownloadError, is DownloadStatus.DownloadNetworkChangesFlow -> {
            RoundedCornersBorder {
                Text(
                    text = stringResource(id = R.string.app_up_data),
                    modifier = Modifier.padding(0.dp,0.dp,0.dp,5.dp),
                    style = MaterialTheme.typography.h6
                )
                Text(
                    text = if(downloadStatus is DownloadStatus.DownloadNetworkChangesFlow) "当前使用移动网络，是否继续更新" else "下载失败，请检查网络",
                    modifier = Modifier.padding(0.dp, 8.dp),
                    style = MaterialTheme.typography.body1
                )
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(IntrinsicSize.Min), horizontalArrangement = Arrangement.End
                ) {
                    TextButton(onClick = {
                        finish()
                    }) {
                        Text(
                            text = "取消",
                            style = TextStyle(color = Color(0xFF00B2EE), fontSize = 16.sp)
                        )
                    }
                    Spacer(modifier = Modifier.width(5.dp))
                    TextButton(onClick = {
                        if (ClickUtils.isFastDoubleClick()) return@TextButton
                        lastUpdate?.app_url?.let {
                            scope.launch {
                                DataStoreManager.upDataVersion.collect { version ->
                                    val split = version.split(",")
                                    checkUpdateViewModel.download(
                                        it,
                                        split[0].toLong(),
                                        split[1].toLong(),
                                        lastUpdate.app_version_number,
                                        split[2]
                                    )
                                }
                            }
                        }
                    }) {
                        Text(
                            text = if(downloadStatus is DownloadStatus.DownloadNetworkChangesFlow) "继续" else "重试",
                            style = TextStyle(color = Color(0xFFE91E63), fontSize = 16.sp)
                        )
                    }
                }
            }
        }
        is DownloadStatus.DownloadSuccess -> {
            (downloadStatus as DownloadStatus.DownloadSuccess).file?.let {
                install(LocalView.current.context, it)
                finish()
            }
        }
        is DownloadStatus.DownloadProcess -> {
            val process = downloadStatus as DownloadStatus.DownloadProcess
            RoundedCornersBorder {
                Text(text = stringResource(id = R.string.app_up_data), modifier = Modifier.padding(0.dp,0.dp,0.dp,5.dp), style = MaterialTheme.typography.h6)
                Box(modifier = Modifier
                    .fillMaxWidth()
                    .padding(0.dp, 8.dp)) {
                    Text(
                        text = "${process.currentLength/1024/1024}MB/${process.length/1024/1024}MB   ${
                            NetWorkManager.getNetSpeed(LocalView.current.context)}",
                        modifier = Modifier.align(Alignment.CenterStart),
                        style = MaterialTheme.typography.body1
                    )
                    Text(
                        text = "${(process.process*100).toInt()}%",
                        modifier = Modifier.align(Alignment.CenterEnd),
                        style = MaterialTheme.typography.body1
                    )
                }
                LinearProgressIndicator(
                    progress = process.process, modifier = Modifier
                        .fillMaxWidth()
                        .padding(0.dp, 0.dp, 0.dp, 8.dp),
                    color = Color(0xFF00B2EE)
                )
            }
        }
        else -> {}
    }
}

@Composable
fun CheckUpdate(checkUpdateViewModel: CheckUpdateViewModel = viewModel(),finish: ()->Unit) {
    val downloadStatus by checkUpdateViewModel.downloadStatus.collectAsState()
    when(downloadStatus){
        is DownloadStatus.DownloadError ,is DownloadStatus.DownloadSuccess,
        is DownloadStatus.DownloadNetworkChangesFlow,
        is DownloadStatus.DownloadProcess ->{ DownloadProgress { finish() } }
        else -> { VersionInformation{ finish() } }
    }

}

@Composable
fun RoundedCornersBorder( content: @Composable ColumnScope.() -> Unit){
    Box(modifier = Modifier
        .fillMaxSize()
        .background(Color(0x80000000)),
        contentAlignment = Alignment.Center) {
        Column(modifier = Modifier
            .wrapContentHeight()
            .padding(20.dp, 0.dp)
            .fillMaxWidth()
            .shadow(elevation = 3.dp, shape = RoundedCornerShape(5.dp))
            .background(color = MaterialTheme.colors.background)
            .padding(20.dp),
            content = content)
        BackHandler(true) {

        }
    }
}

private fun install(context: Context, apk: File){
    val intent = Intent(Intent.ACTION_VIEW)
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        //注意第二个参数，要保持和manifest中android:authorities的值相同
        val uri = FileProvider.getUriForFile(
            context,
            context.packageName.toString() + ".fileProvider",
            apk
        )
        intent.setDataAndType(uri, "application/vnd.android.package-archive")
    } else {
        intent.setDataAndType(Uri.fromFile(apk), "application/vnd.android.package-archive")
    }
    try {
        context.startActivity(intent)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

